'''
@Version: 0.0.2
@Author: ider
@Date: 2019-12-27 11:29:07
LastEditors: ider
LastEditTime: 2021-07-06 17:39:58
@Description: 计算学科内的小世界图,其实这个不用算
'''

import graph_tool.all as gt
import numpy as np

import logging


class Graph:
    """
    最大联通分量
    """
    def __init__(self,edges,isDirected=False):
        # 无向图
        self.graph = gt.Graph(directed=isDirected)
        # 添加所有的边
        if isinstance(edges,list):
            self.graph.add_edge_list(edges,hashed=False)
        else:
            self.graph.add_edge_list(edges(),hashed=False)
        # 去除重复边
        gt.remove_parallel_edges(self.graph)
        # 获得联通子图
        self.component_graph = gt.extract_largest_component(self.graph)
        
    def get_avg_path_and_unique(self):
        
#         vertex_avgs = gt.vertex_average(self.component_graph, all_sp)
#         return float(np.mean(vertex_avgs[0]))
        # 默认使用 int32 这里替换为 int8 节省内存
        # 使用全图的矩阵，这样可以从矩阵中映射到点
        # 强连通图，不存在 255
        self.all_sp = self.graph.new_vertex_property("vector<%s>" % 'int8_t')
        gt.shortest_distance(self.component_graph,dist_map=self.all_sp)

        vvvv = self.all_sp.get_2d_array(np.arange(self.graph.num_vertices()))
        unique, counts = np.unique(vvvv, return_counts=True)
        if len(counts)  == 0 :
            print("count size 0",unique)
            ave = None
        else:
            ave = float(np.sum(vvvv)/(self.component_graph.num_vertices()**2-self.component_graph.num_vertices()))
        return ave,unique, counts

        # return float(np.sum([np.sum(i.get_array()) for i in self.all_sp])/(self.component_graph.num_vertices()**2-self.component_graph.num_vertices()))

    def get_clustering_coefficient(self):
        clust = gt.local_clustering(self.component_graph)
        vertex_avgs =gt.vertex_average(self.component_graph, clust)
        return vertex_avgs[0]
    
    def get_num_edges(self):
        return self.component_graph.num_edges()
    
    def get_num_vertices(self):
        return self.component_graph.num_vertices()


class GraphEX:
    '''
    调和有向网络，不处理最大联通分量
    '''
    def __init__(self,edges,isDirected=False):
        # 无向图
        self.graph = gt.Graph(directed=isDirected)
        # 添加所有的边
        if isinstance(edges,list):
            self.graph.add_edge_list(edges,hashed=False)
        else:
            self.graph.add_edge_list(edges(),hashed=False)
        # 去除重复边
        gt.remove_parallel_edges(self.graph)
        
    def get_avg_path_and_unique(self):
        # 默认使用 int32 这里替换为 int8 节省内存
        self.all_sp = self.graph.new_vertex_property("vector<%s>" % 'int8_t')
        gt.shortest_distance(self.graph,dist_map=self.all_sp)
        vvvv = self.all_sp.get_2d_array(np.arange(self.graph.num_vertices()))
        unique, counts = np.unique(vvvv, return_counts=True)
        if len(counts)  == 0 :
            print("count size 0",unique)
            ave = None
        else:
            ave = float(np.sum(vvvv[vvvv!=255])/(self.graph.num_vertices()**2-self.graph.num_vertices()-int(counts[-1])))
        return ave,unique, counts

    def get_clustering_coefficient(self):
        clust = gt.local_clustering(self.graph)
        vertex_avgs =gt.vertex_average(self.graph, clust)
        return vertex_avgs[0]
    
    def get_num_edges(self):
        return self.graph.num_edges()
    
    def get_num_vertices(self):
        return self.graph.num_vertices()
